/**
 * JWT工具类，用于生成或解析json web token字符串
 */
package com.cnfangmao.util;

import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator.Builder;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;


public class JWTUtil {
	private static Logger logger=Logger.getLogger(JWTUtil.class);
	public final static String HEADER_ALG="HS256";
	public final static String HEADER_TYPE="JWT";
	
	/****
	 * 根据一个实体对象生成对应的jwt字符串
	 * @param entity
	 * @param nExpired
	 * @param strPassword
	 * @return
	 */
	public static String getJWT(Object entity,int nExpired,String strPassword)
	{
		String strJWT=StringUtils.EMPTY;
		
		Map<String,Object> mapHeaders=new HashMap<String,Object>();
		mapHeaders.put("alg", HEADER_ALG);
		mapHeaders.put("type", HEADER_TYPE);
		
        Date expiresDate =new Date(new Date().getTime()+nExpired*1000*60);


		Builder builder=JWT.create();
		builder.withHeader(mapHeaders);
		
		if(nExpired>0)
		{
			builder.withExpiresAt(expiresDate)
			.withIssuedAt(new Date());
		}
		
		for(Field field:ReflectUtil.getDeclaringFields(entity.getClass()))
		{
			try 
			{
				field.setAccessible(true);
				Object fvalue=field.get(entity);
				if(fvalue!=null)
				{
					if(field.getType()==Timestamp.class)
					{
						long lTimestamp=((Timestamp)fvalue).getTime();
						builder.withClaim(field.getName(), lTimestamp);
					}
					else
					{
						builder.withClaim(field.getName(), fvalue.toString());
					}
				}
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		}
		
		strJWT=builder.sign(Algorithm.HMAC256(strPassword));
		return strJWT;
	}
	
	public static Object getObjectFromJWT(Class<?> clazz,String strJWT)
	{
		Object entity=null;
		
		DecodedJWT jwt = JWT.decode(strJWT);
		Date expiredDate=jwt.getExpiresAt();
		if(expiredDate==null || expiredDate.after(new Date()))
		{//没过期
			try {
				entity=clazz.newInstance();
				for(Field field:ReflectUtil.getAllFields(clazz))
				{
					if(!ReflectUtil.isFinal(field))
					{
						field.setAccessible(true);
						
						if(jwt.getClaim(field.getName())!=null)
						{

							boolean b=jwt.getClaim(field.getName()).isNull();
							if(field.getType()==Timestamp.class)
							{
								long lTimestamp=jwt.getClaim(field.getName()).asLong();
								field.set(entity, new Timestamp(lTimestamp));
							}
							else
							{
								field.set(entity, jwt.getClaim(field.getName()).as(field.getType()));
							}
							
							
						}
					}
				}
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}

		}
		
		return entity;
	}
}
